package org.e_gold.factory;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.e_gold.dao.CEventDAO;
import org.e_gold.dao.ConfigDAO;
import org.e_gold.dao.CountryDAO;
import org.e_gold.dao.LeagueDAO;
import org.e_gold.dao.UserAccountDAO;
import org.e_gold.model.Config;
import org.e_gold.model.UserAccount;
import org.e_gold.service.ConfigService;
import org.e_gold.service.impl.ConfigServiceImpl.betConfig;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * @author Thang Nguyen
 */
@Component
@Scope("singleton")
public class ConfigCrawler extends Thread{

	private static final Logger logger = Logger.getLogger(ConfigCrawler.class);

	public LinkedList<Object> queue = new LinkedList<Object>();
	private String CONFIG_URL;
	private String MONITOR_KEY;
	//	private final String USER_ACCOUNT_ID = "2";
	private final String CONFIG_TYPE = "setting";
	private int SLEEP_TIME = 20 * 1000;
	private final String CONFIG_SEPERATE = "xx00xx";

	private boolean initialized = false;

	@Autowired
	private AppProperties appProperties;

	@Autowired
	private CEventDAO cEventDAO;

	@Autowired
	private CountryDAO countryDAO;

	@Autowired
	private LeagueDAO leagueDAO;

	@Autowired
	private UserAccountDAO userAccountDAO;

	@Autowired
	private ConfigService configService;

	@Autowired
	private ConfigDAO configDAO;

	public void init(){
		CONFIG_URL = appProperties.getConfigUrl();
		MONITOR_KEY = appProperties.getMonitorKey();
		initialized = true;
	}

	@Override
	public void run() {
		try{
			while(true){
				try{
					if(!initialized){
						init();
					}
					logger.info("<<<Config Crawler started....");
					hookConfig();
					logger.info("<<<Config Crawler done....");
					Thread.sleep(SLEEP_TIME);
				}catch(Exception ex){
					logger.info("Config Crawler  queue bug!");
					logger.error(ToStringBuilder.reflectionToString(ex, ToStringStyle.SHORT_PREFIX_STYLE));
					ex.printStackTrace();
					Thread.sleep(3000);
				}
			}
		}catch(Exception ex){
			logger.info("Config crawler stopped!!!");
			logger.error(ToStringBuilder.reflectionToString(ex, ToStringStyle.SHORT_PREFIX_STYLE));
			ex.printStackTrace();
		}
	}

	private void hookConfig() throws Exception{
		try{
			Map<String, String> formData = new HashMap<String, String>();
			formData.put("type", CONFIG_TYPE);

			String ret = post(CONFIG_URL, formData);
			if(!StringUtils.isEmpty(ret) && ret.contains(CONFIG_SEPERATE)){
				getConfigSetting(ret);
			}
		}catch(Exception ex){
			logger.error(ToStringBuilder.reflectionToString(ex, ToStringStyle.SHORT_PREFIX_STYLE));
			throw ex;
		}
	}

	private void getConfigSetting(String data){
		try{
			data = data.replace("\"", "");
			String[] parts = data.split(CONFIG_SEPERATE);
			String strCountryId = parts[0];
			String strLeagueId = parts[1];
			String userStatus = parts[2];
			String betTimes = parts[3];
			String betSetting = parts[4];

			//update country & league to active
			countryDAO.activeCountry(strCountryId);
			leagueDAO.activeLeague(strLeagueId);

			//update user status
			UserAccount user = userAccountDAO.getCurrentUser();
			user.setActive(userStatus.equals("1"));
			userAccountDAO.update(user);

			//update betting rule
			String[] str = betTimes.split(";");
			Config cfgBetTimes = configService.get(betConfig.BET_TIMES.toString());
			Config cfgBaseAmount = configService.get(betConfig.BASE_AMOUNT.toString());
			Config cfgWonPercent = configService.get(betConfig.WON_PERCENT.toString());
			Config cfgSettingConfig = configService.get(betConfig.BET_SETTING.toString());

			cfgBetTimes.setValue(str[0]);
			cfgBaseAmount.setValue(str[1]);
			cfgWonPercent.setValue(str[2]);
			cfgSettingConfig.setValue(betSetting);

			List<Config> lstConfig = Arrays.asList(cfgBetTimes, cfgBaseAmount, cfgWonPercent, cfgSettingConfig);
			configDAO.update(lstConfig);

		}catch(Exception ex){
			logger.info("Can't get config setting: " + data);
			ex.printStackTrace();
		}
	}

	private String post(String url, Map<String, String> formData){
		String str = "";
		try {
			formData.put("validate", MONITOR_KEY);
			Connection connection = Jsoup.connect(url);
			connection.timeout(300000).data(formData);
			Document doc = connection.get();

			str = doc.body().text();
		} catch(NumberFormatException nfe){
		} catch (Exception e) {
			logger.error(e);
			e.printStackTrace();
		}
		return str;
	}
}
